<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>{{ title }}</title>
    <script src="{{ interpreterSourceFile }}" defer integrity="{{ SRIHash }}"></script>
    <style>
      body {
          font-family: sans-serif;
          margin: 0 auto;
          max-width: 799px;
          line-height: 1.6;
          font-size: 18px;
          padding-bottom: 3em;
          background-color: {{background-color}};
      }
      th{ 
        text-align: left;
        background-color: #eee;
      }
      tr:nth-child(even) {
        background-color: #f3f3f3;
      }
      pre {
        background-color:#eee;
      }

      h1,
      h2,
      h3 {
          line-height: 1.2;
      }
    </style>
  </head>

  <body>
    <h1>{{title}}</h1>
    <p>
      In your <code>head</code>:
    </p>

    <pre>&lt;script 
  src="https://state-machine-cat.js.org/state-machine-cat-inpage.min.js"
  defer>
&lt;/script></pre>

    <p>In your <code>body</code>:</p>
    <pre>
&lt;script type="text/x-smcat">
  on [color="darkgreen" active],
  off [color="maroon"];

  on => off [color="red"]: flickSwitch()
    / makeNoise("off.wav");
  off => on [color="#009900"]: flickSwitch()
    / makeNoise("on.wav");
&lt;/script></pre>
    <p>result:</p>
    <center>
    <script type="text/x-smcat">
      on [color="darkgreen" active],
      off [color="maroon"];

      on => off [color="red"]: flickSwitch()
        / makeNoise("off.wav");
      off => on [color="#009900"]: flickSwitch()
        / makeNoise("on.wav");
    </script>
    </center>
    

    <h2>Introduction</h2>
    <p>
      When you include the state-machine-cat 'inpage' script in the head of your
      page like so ...
    </p>
    <pre>&lt;script 
  src="https://state-machine-cat.js.org/state-machine-cat-inpage.min.js"
  defer>
&lt;/script></pre>
    <p>
      ... it will extend html with three script types, which will render into state
      machine diagrams:
      <table>
        <thead><tr><th>type</th><th>what's it do?</th></tr></thead>
        <tbody>
          <tr>
            <td>
              <code>text/x-smcat</code>
            </td>
            <td>accepts <code>smcat</code></td>
          </tr>
          <tr>
            <td>
              <code>text/x-scxml</code>
            </td>
            <td>accepts <code>SCXML</code></td>
          </tr>
          <tr>
            <td>
              <code>text/x-smcat-json</code>
            </td>
            <td>accepts smcat's abstract syntax tree format</td>
          </tr>
        </tbody>
      </table>
    </p>

    <p>
      When that is done, you can use <code>script</code>s with one of the types
      above in the body of your page (e.g. <code>&lt;script type="text/x-smcat">a=>b;&lt;/script></code>).
    </p>
    <p>
      These scripts take optional <code>data</code> attributes you
      can use to influence how things get rendered:
      <table>
        <thead>
          <tr>
            <th>attribute</th>
            <th>description</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>
              <code>data-direction</code>
            </td>
            <td>
              Direction the graph should be rendered in. Possible values: 
              <code>top-down</code> (default),
              <code>left-right</code>,
              <code>bottom-top</code>,
              <code>right-left</code>.
            </td>
          </tr>
          <tr>
            <td>
              <code>data-output-type</code>
            </td>
            <td>
              What you want to have rendered. Defaults to <code>svg</code> 
              (for diagrams), but it's also possible to re-render the state machine
              in one of the avaible description languages: <code>smcat</code>,
              <code>scxml</code> and <code>json</code>.
            </td>
          </tr>
          <tr>
            <td>
              <code>data-engine</code>
            </td>
            <td>
              state-machine-cat currently uses <a href="https://graphviz.org">GraphViz</a>
              as a render engine. With the `data-engine` attribute it's possible
              to influence which layout algorithm GraphViz uses. By default 
              it's <code>dot</code>, but it's also possible to specify other values are e.g. 
              <code>fdp</code> or <code>osage</code>.
            </td>
          </tr>
          <tr>
            <td>data-desugar</td>
            <td>Boolean attribute that, when included, will make the render engine 
              <a href="https://github.com/sverweij/state-machine-cat/blob/master/docs/desugar.md">desugar</a>
              the diagram.
            </td>
          </tr>
        </tbody>
      </table>
    </p>

    <h2>Examples</h2>

    <h3>Read from an url</h3>
    <p>Pass the url in the <code>src</code> attribute of the script tag:</p>
    <pre>&lt;script type="text/x-smcat" <mark>src="samples/cat.smcat"</mark>>&lt;/script></pre>
    <center>
      <script type="text/x-smcat" src="{{root}}samples/cat.smcat"></script>
    </center>

    <h2>Orientation with <code>data-direction</code></h2>
    <p>
      In this example the states get layed out from left to right instead of top down because
      the script includes the <code>data-direction</code> attribute:
    </p>
    <pre>
&lt;script 
  type="text/x-smcat"
  src="samples/cassetteplayer.smcat"
  <mark>data-direction="left-right"</mark>>
&lt;/script></pre>
    <center>
      <script type="text/x-smcat" src="{{root}}samples/cassetteplayer.smcat" data-direction="left-right"></script>
    </center>

    <h2>De-sugaring a state machine</h2>
    <p>
      If you want to render a state machine without any pseudo states that only
      exist for 'syntactic sugar', you can do this with the `data-desugar`
      attribute.
    </p>
    <h3>as is</h3>
    <pre>
&ltscript 
  src="samples/desugarable.smcat" 
  type="text/x-smcat" 
  data-direction="left-right" 
&lt/script></pre>

    <script src="{{ root }}samples/desugarable.smcat" type="text/x-smcat" data-direction="left-right"></script>
    
    <h3>de-sugared</h3>
    <pre>
&ltscript 
  src="samples/desugarable.smcat" 
  type="text/x-smcat" 
  data-direction="left-right" 
  <mark>data-desugar=true</mark>>
&lt/script></pre>
    <p>
      You'll notice the <em>choice</em> is replaced by two regular transitions 
      and the <em>junction</em> on the right with all permutations of transitions
      it describes:
    </p>
    <script src="{{ root }}samples/desugarable.smcat" type="text/x-smcat" data-desugar=true data-direction="left-right"></script>


    <h2>Using SCXML</h2>
    <p>
      It's possible to embed SCXML:
    </p>
    <pre>
&lt;script <mark>type="text/x-scxml"</mark>>
  &lt;scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0">
    &lt;state id="off">
      &lt;onentry>&lt;log expr="winston.log('switched lamp on')"/>&lt;/onentry>
      &lt;transition event="switch_flipped" target="on"/>
    &lt;/state>
    &lt;state id="on">
      &lt;transition event="switch_flipped" target="off"/>
    &lt;/state>
  &lt;/scxml>
&lt;/script></pre>
    <center>
      <script type="text/x-scxml">
        <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0">
          <state id="off">
            <onentry><log expr="winston.log('switched lamp on')"/></onentry>
              <transition event="switch_flipped" target="on"/>
          </state>
          <state id="on">
            <transition event="switch_flipped" target="off"/>
          </state>
        </scxml>
      </script>
    </center>

    <p>
      or likewise, using a <code>src</code> attribute to load SCXML from somewhere
      else:
    </p>
    <pre>&ltscript <mark>type="text/x-scxml" src="samples/sprint-states.scxml"</mark>>&lt/script></pre>
    <center>
      <script type="text/x-scxml" src="{{root}}samples/sprint-states.scxml"></script>
    </center>
 
    <h2>Output formats other than <code>svg</code></h2>
    <p>
      If you, for some reason don't want to render an svg, but one of the textual
      formats, you can specify an output type. This example specifies <code>json</code>
      to show the abstract syntax tree (AST):
    </p>
    <pre>&lt;script type="text/x-smcat" data-output-type="json">
  off: entry/ &lt;log expr="winston.log('switched lamp on')"/>,
  on;

  off => on: switch_flipped;
  on => off: switch_flipped;
&lt;/script></pre>

    <p>which will render this AST:</p>
    <script type="text/x-smcat" data-output-type="json">
off: entry/ <log expr="winston.log('switched lamp on')"/>,
on;

off => on: switch_flipped;
on => off: switch_flipped;</script>

    <h2>Error handling</h2>
    <p>
      When the render engine detects an error it will show the error. E.g. 
      trying to render an invalid script, like so...
    </p>
    <pre>&lt;script type="text/x-smcat">a => nosemicolon&lt;/script></pre>

    <p>
      ... will yield this:
    </p>

    <script type="text/x-smcat">a => nosemicolon</script>

    <p>
      ... or when it couldn't find the script at the other end of the URL ...
    </p>

    <pre>&lt;script src="this_thing_doesnot_exist" type="text/x-smcat"/></pre>

    <script src="this_thing_doesnot_exist" type="text/x-smcat"></script>

    {{#if dev}}
    <h2>Error scenarios for the inpage script</h2>

    <h3>no textContent</h3>
    <script type="text/x-smcat"></script>

    <h3>syntax error in scxml</h3>
    <script type="text/x-scxml"><</script>
    <h3>syntax error in smcat source</h3>
    <script type="text/x-smcat">no_semicolon</script>

    <h2>DHCP</h2>
    <script src="{{ root }}samples/DHCP.smcat" type="text/x-smcat"></script>
    {{/if}}
  </body>
</html>
